import winim/lean
import winim/inc/[winuser]
import std/[locks, times, os, strutils, random]
# import system/threads
# winbase
var
  lis: array[0..2, string] = ["#签到", "#打卡", "#美滋滋"] 
  liswords: array[0..129, string] = ["生姜烧,","鳜鱼,", "蒜蓉汤,","鲑鱼,","杏鲍菇,",
    "鲍鱼,","醋饭,", "鲷鱼烧,","拉面,","海鲜汤,",
    "牛尾汤,","橙醋蟹,", "海胆汤,","炒牡蛎,","大阪烧,",
    "春卷,","泡菜烧,", "鸡肉串,","铜锣烧,","荞麦面,",
    "鳗鱼饭,","苹果饼,", "奶酪饼,","玉子烧,","糖醋排骨,",
    "明太鱼,","鳕鱼烧,", "五花肉,","章鱼烧,","西京烧,",
    "麻婆豆腐,","担担面,", "里脊,","牛舌,","泡菜鱼,",
    "牛肉煮,","盐渍鲭鱼", "虾仁,","牛霖肉,","三文鱼,",
    "酒蒸蛤蜊", "关东煮", "寿喜锅", "三明治", "蛋包饭",
    "牛肉饭", "石狩锅", "昆布", "海苔", "酱汁",
    "水饺", "饺子", "煎饺", "蒸饺", "酱油拌面",
    "牛油果", "牛腩", "牛肚", "牛肝", "鸡蛋烧",
    "鱿鱼汤", "鲤鱼汤", "乌贼面", "寿司", "冷面",
    "炒年糕", "安康鱼", "纳豆饭", "油泼面", "山葵盖饭",
    "蚬汤", "蚬子面", "生姜烧", "鳜鱼", "蒜蓉汤",
    "鲑鱼", "杏鲍菇", "鲍鱼", "味噌汤", "烤肉",
    "炸鸡块", "羊排", "番茄炒蛋", "肝盖饭", "信玄袋",
    "鲔鱼汤", "喜知次", "龙虾", "肉串", "鸡蛋卷",
    "大福", "牛筋", "梅子酒", "线鱼脊", "云吞面",
    "刺鲳鱼","虾肉山芋", "汉堡肉", "番茄意面", "排骨面",
    "咖喱饭", "咖喱牛肉", "蕃茄豆腐", "秋刀鱼", "什锦面",
    "鱼生碎","葱炒肉", "熏肠", "沙丁鱼", "什锦拌",
    "花蛤", "糯米饭", "鸡肉春卷", "炒培根", "红糟排骨",
    "黑炒饭", "麻辣汤","竹荚鱼", "玉米饼", "腊肉",
    "爆羊肉", "绿麻豆腐", "烧虾仁", "鱼丸面", "煲仔饭",
    "肠炒面", "青花鱼", "横膈膜肉", "麻婆凉面", "肉汁乌冬"]

var
  tri: array[0..3, Thread[tuple[num, keyno, iinterval: int]]]
  L: Lock
  isWord: bool = false

proc time_count(interval:int = 2) = 
  var
    t1 = now()
    t2 = now() + initDuration(minutes = interval) 
  echo "current time[$1]" % [t1.format("HH:mm:ss")]
  echo "\n[$#] would be coming." % [t2.format("HH:mm:ss")]

proc mykey_press_release_u(keyno: int = 1) = 
  # key 1 : 0x31 or 49
  # key 2 : 0x32 or 50
  # key 3 : 0x33 or 51
  # ctrl  : 0x11 or 17
  # alt   : 0x12 or 18

  # 按下ctrl+v
  # win32api.keybd_event(0x11, 0, 0, 0)
  # win32api.keybd_event(0x56, 0, 0, 0)
  # win32api.keybd_event(0x56, 0, win32con.KEYEVENTF_KEYUP, 0)
  # win32api.keybd_event(0x11, 0, win32con.KEYEVENTF_KEYUP, 0)
  # time.sleep(1)
  # # 按下回车
  # win32api.keybd_event(0x0D, 0, 0, 0)
  # win32api.keybd_event(0x0D, 0, win32con.KEYEVENTF_KEYUP, 0)
  if 1 == keyno:
    keybd_event(0x11, 0, 0, 0)
    keybd_event(0x31, 0, 0, 0)
    keybd_event(0x31, 0, KEYEVENTF_KEYUP, 0)
    keybd_event(0x11, 0, KEYEVENTF_KEYUP, 0)
  elif 2 == keyno:
    keybd_event(0x11, 0, 0, 0)
    keybd_event(0x32, 0, 0, 0)
    keybd_event(0x32, 0, KEYEVENTF_KEYUP, 0)
    keybd_event(0x11, 0, KEYEVENTF_KEYUP, 0)
  elif 3 == keyno:
    keybd_event(0x11, 0, 0, 0)
    keybd_event(0x33, 0, 0, 0)
    keybd_event(0x33, 0, KEYEVENTF_KEYUP, 0)
    keybd_event(0x11, 0, KEYEVENTF_KEYUP, 0)
  elif 4 == keyno:
    keybd_event(0x11, 0, 0, 0)
    keybd_event(0x34, 0, 0, 0)
    keybd_event(0x34, 0, KEYEVENTF_KEYUP, 0)
    keybd_event(0x11, 0, KEYEVENTF_KEYUP, 0)
  elif 5 == keyno:
    keybd_event(0x11, 0, 0, 0)
    keybd_event(0x35, 0, 0, 0)
    keybd_event(0x35, 0, KEYEVENTF_KEYUP, 0)
    keybd_event(0x11, 0, KEYEVENTF_KEYUP, 0)
  elif 6 == keyno:
    keybd_event(0x11, 0, 0, 0)
    keybd_event(0x36, 0, 0, 0)
    keybd_event(0x36, 0, KEYEVENTF_KEYUP, 0)
    keybd_event(0x11, 0, KEYEVENTF_KEYUP, 0)
  elif 7 == keyno:
    keybd_event(0x11, 0, 0, 0)
    keybd_event(0x37, 0, 0, 0)
    keybd_event(0x37, 0, KEYEVENTF_KEYUP, 0)
    keybd_event(0x11, 0, KEYEVENTF_KEYUP, 0)

proc getContentFromClipboared(hData, phw:HWND) = 
  # content = lis[0]
  # initil hData
  # hData = GlobalAlloc(GMEM_MOVEABLE, sizeof(content)+1)
  # pData = cast[LPWSTR](GlobalLock(hData))
  # lstrcpy(pData, content)
  # GlobalUnlock(hData)

  OpenClipboard(phw)
  EmptyClipboard()
  # CF_TEXT 
  # SetClipboardData(CF_TEXT, hData)
  # GetClipboardData(CF_TEXT)
  SetClipboardData(CF_UNICODETEXT, hData)
  GetClipboardData(CF_UNICODETEXT)
  CloseClipboard()
  # SendMessage(phw, WM_PASTE, 0, 0);
  PostMessage(phw, WM_PASTE, 0, 0);
  sleep(300)
  # Ctrl+V
  keybd_event(0x11, 0,0,0)
  keybd_event(0x56, 0,0,0)
  keybd_event(0x56, 0, KEYEVENTF_KEYUP,0)
  keybd_event(0x11, 0, KEYEVENTF_KEYUP,0)

proc directPaste(phw: HWND) =
  SendMessage(phw, WM_PASTE, 0, 0)
  sleep(1000)
  # Ctrl+V
  keybd_event(0x11, 0,0,0)
  keybd_event(0x56, 0,0,0)
  keybd_event(0x56, 0, KEYEVENTF_KEYUP,0)
  keybd_event(0x11, 0, KEYEVENTF_KEYUP,0)

proc findWindowFromPoint_words(keyno: int = 1,iinterval:int =2) =
  {.gcsafe.}: 
    var 
      phw: HWND

    var
      pointold: LPPOINT
      point: POINT
    
    var
      # content: seq[LPWSTR]
      pData, content: LPWSTR
      hData: HWND

    content = lis[1]
    # # content = "加油" & ","
    # if 1 == keyno:
    #   # content = "#打卡"
    #   content = lis[2]
    # # initil hData
    # hData = GlobalAlloc(GMEM_MOVEABLE, sizeof(content)+2)
    # pData = cast[LPWSTR](GlobalLock(hData))
    # lstrcpy(pData, content)
    # GlobalUnlock(hData)

    point.x = 1347
    point.y = 761
    # pointold.x = 1347
    # pointold.y = 761  
    GetCursorPos(pointold)
    mykey_press_release_u(keyno)
    phw = WindowFromPoint(cast[POINT](pointold))
    sleep(1000)
    time_count(iinterval)
    sleep(1000)
    ShowWindow(phw, SW_SHOW)
    SetCursorPos(1347, 761)
    mouse_event(MOUSEEVENTF_LEFTDOWN, 1394, 764, 0, 0)
    mouse_event(MOUSEEVENTF_LEFTUP, 1394, 764, 0, 0)
    sleep(500)
    # getContentFromClipboared(hData, phw)
    # # mouse_event(MOUSEEVENTF_LEFTUP, 1394, 764, 0, 0)
    # # sleep(2000)

    # # OpenClipboard(phw)
    # # EmptyClipboard()
    # # # CF_TEXT 
    # # # SetClipboardData(CF_TEXT, hData)
    # # # GetClipboardData(CF_TEXT)
    # # SetClipboardData(CF_UNICODETEXT, hData)
    # # GetClipboardData(CF_UNICODETEXT)
    # # CloseClipboard()
    # # SendMessage(phw, WM_PASTE, 0, 0)
    # # sleep(1000)
    # # # Ctrl+V
    # # keybd_event(0x11, 0,0,0)
    # # keybd_event(0x56, 0,0,0)
    # # keybd_event(0x56, 0, KEYEVENTF_KEYUP,0)
    # # keybd_event(0x11, 0, KEYEVENTF_KEYUP,0)
    # sleep(300)
    # # Enter Key Press
    # keybd_event(VK_RETURN, 0,0,0)
    # keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP,0)
    # # SendMessage(phw, WM_KEYDOWN, VK_RETURN, 0)
    # # SendMessage(phw, WM_KEYUP, VK_RETURN, 0)
    # sleep(1000)

    if 3 == keyno:
      var 
        old_idx: int = -1
        tmp_idx: int
      randomize()
      for i in 0..4:
        tmp_idx = rand(high(liswords))
        if tmp_idx != old_idx:
          old_idx = tmp_idx
        else:
          tmp_idx = 130 mod 7
        content = liswords[tmp_idx]
        hData = GlobalAlloc(GMEM_MOVEABLE, sizeof(content)+2)
        pData = cast[LPWSTR](GlobalLock(hData))
        lstrcpy(pData, content)
        GlobalUnlock(hData)
        getContentFromClipboared(hData, phw)
        sleep(500)
        keybd_event(VK_RETURN, 0,0,0)
        keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP,0)
        sleep(900)
        sleep(2000)

proc findWindowFromPoint(keyno: int = 1,iinterval:int =2) =
  {.gcsafe.}: 
    var 
      phw: HWND

    var
      pointold: LPPOINT
      point: POINT
    
    var
      # content: seq[LPWSTR]
      pData, content: LPWSTR
      hData: HWND

    content = lis[1]
    # content = "加油" & ","
    if 1 == keyno:
      # content = "#打卡"
      content = lis[2]
    # initil hData
    hData = GlobalAlloc(GMEM_MOVEABLE, sizeof(content)+2)
    pData = cast[LPWSTR](GlobalLock(hData))
    lstrcpy(pData, content)
    GlobalUnlock(hData)

    point.x = 1347
    point.y = 761
    # pointold.x = 1347
    # pointold.y = 761  
    GetCursorPos(pointold)
    mykey_press_release_u(keyno)
    phw = WindowFromPoint(cast[POINT](pointold))
    sleep(1000)
    time_count(iinterval)
    sleep(1000)
    ShowWindow(phw, SW_SHOW)
    SetCursorPos(1347, 761)
    mouse_event(MOUSEEVENTF_LEFTDOWN, 1394, 764, 0, 0)
    mouse_event(MOUSEEVENTF_LEFTUP, 1394, 764, 0, 0)
    sleep(500)
    getContentFromClipboared(hData, phw)
    # mouse_event(MOUSEEVENTF_LEFTUP, 1394, 764, 0, 0)
    # sleep(2000)

    # OpenClipboard(phw)
    # EmptyClipboard()
    # # CF_TEXT 
    # # SetClipboardData(CF_TEXT, hData)
    # # GetClipboardData(CF_TEXT)
    # SetClipboardData(CF_UNICODETEXT, hData)
    # GetClipboardData(CF_UNICODETEXT)
    # CloseClipboard()
    # SendMessage(phw, WM_PASTE, 0, 0)
    # sleep(1000)
    # # Ctrl+V
    # keybd_event(0x11, 0,0,0)
    # keybd_event(0x56, 0,0,0)
    # keybd_event(0x56, 0, KEYEVENTF_KEYUP,0)
    # keybd_event(0x11, 0, KEYEVENTF_KEYUP,0)
    sleep(300)
    # Enter Key Press
    keybd_event(VK_RETURN, 0,0,0)
    keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP,0)
    # SendMessage(phw, WM_KEYDOWN, VK_RETURN, 0)
    # SendMessage(phw, WM_KEYUP, VK_RETURN, 0)
    sleep(1000)
    # if 3 == keyno and isWord == true:
    #   var 
    #     old_idx: int = -1
    #     tmp_idx: int
    #   randomize()
    #   for i in 0..4:
    #     tmp_idx = rand(high(liswords))
    #     if tmp_idx != old_idx:
    #       old_idx = tmp_idx
    #     else:
    #       tmp_idx = 130 mod 7
    #     content = liswords[tmp_idx]
    #     hData = GlobalAlloc(GMEM_MOVEABLE, sizeof(content)+2)
    #     pData = cast[LPWSTR](GlobalLock(hData))
    #     lstrcpy(pData, content)
    #     GlobalUnlock(hData)
    #     getContentFromClipboared(hData, phw)
    #     sleep(500)
    #     keybd_event(VK_RETURN, 0,0,0)
    #     keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP,0)
    #     sleep(900)
    #     sleep(2000)


proc consumer(nums:tuple[num, keyno, iinterval: int]) {.thread.} = 
  #[consumer function]#
  {.gcsafe.}:
    for i in 0..nums.num:
      sleep(1500)
      # echo "----wait for producer running----"
      echo "cer-current thread name is: ", getThreadId() 
      acquire(L)
      if isWord == false:
        findWindowFromPoint(nums.keyno, nums.iinterval)
        if nums.keyno == 3:
          isWord = true
      elif isWord == true and nums.keyno == 3:
        findWindowFromPoint_words(nums.keyno, nums.iinterval)
        isWord = false
      release(L)
      sleep(1000 * 60 * nums.iinterval)

proc run_thread() = 
  #[one producer, three consumer]#
  echo "--------start--------"
  initLock(L)
  # var i = 0
  for i in low(tri)..high(tri):
    if i == 0:
      createThread(tri[i], consumer, (40, i+1, 35))
    if i >= 2 and i < 3:
      createThread(tri[i], consumer, (40, i+1, 20))
    elif i >= 1 and i < 2:
      createThread(tri[i], consumer, (40, i+1, 30))
    elif i == 3:
      createThread(tri[i], consumer, (40, 3, 20))
  # createThread(tri[0], consumer, (40, 1, 20))
  # createThread(tri[1], consumer, (40, 2, 35))
  # createThread(tri[2], consumer, (40, 3, 30))
  # createThread(tri[3], consumer, (40, 4, 30))
  # createThread(tri[4], consumer, (40, 5, 30))
  # createThread(tri[5], consumer, (40, 6, 30))
  # createThread(tri[3], consumer, (40, 6, 30))

  joinThreads(tri)
  deinitLock(L)

run_thread()
